﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NHTU;
using DevComponents.DotNetBar;
using Microsoft.Win32;
using System.Data.Sql;
using System.Threading;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using DevComponents.DotNetBar.Controls;

namespace NOMFinalSettlement.AppForm.App
{
    public partial class fSetting : Office2007Form
    {
        SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();

        public fSetting()
        {
            InitializeComponent();
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void fSetting_Load(object sender, EventArgs e)
        {
            Properties.Settings.Default.Reload();
            styleSettingForm.ManagerStyle = Properties.Settings.Default.AppSkin;

            cmbSqlServer.Text = MainApp.Self.connInfo.DataSource;
            if (MainApp.Self.connInfo.UserID != "")
            {
                chkSqlServer.Checked = true;
                txtUserId.Text = MainApp.Self.connInfo.UserID;
                txtPassword.Text = MainApp.Self.connInfo.Password;
            }
            if (MainApp.Self.connInfo.InitialCatalog != "")
            {
                cmbDatabase.Enabled = true;
                cmbDatabase.Text = MainApp.Self.connInfo.InitialCatalog;
            }

            chkStartup.Checked = Properties.Settings.Default.AppStartUp;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                builderConnect();
                FinalSettlementModel.Properties.Settings.Default.ConnectionString = SQLServer.ConnectionStringEnCrypt(sqlBuilder.ConnectionString);
                FinalSettlementModel.Properties.Settings.Default.Save();
                Properties.Settings.Default.AppStartUp = chkStartup.Checked;
                Properties.Settings.Default.Save();

                MsgBox.Show("Một thao tác liên quan đến dữ liệu hệ thống. Chương trình sẽ tự khởi động lại sau thông báo này.", "Thông báo", MsgBoxButton.Ok, MsgBoxIcon.Success);
                MainApp.Self.askExit = false;
                RestartAppInvoke();
            }
            catch (Exception ex)
            {
                MsgBox.Show("Có lỗi xảy ra: \n" + ex.Message, "Thông báo", MsgBoxButton.Ok, MsgBoxIcon.Warning);
            }
        }

        void RestartAppInvoke()
        {
            this.Invoke(new MethodInvoker(() => MainApp.Self.restartApp()), null);
        }

        // Fix "Cross-thread operation not valid: Control 'btnInstanceName' accessed from a thread other than the thread it was created on."
        void EnableBtn(ButtonX btn, bool yes)
        {
            Invoke(new MethodInvoker(() => btnInstanceName.Visible = yes), null);
        }
        void cmbExAdd(DevComponents.DotNetBar.Controls.ComboBoxEx cmb, string str)
        {
            Invoke(new MethodInvoker(() => cmb.Items.Add(str)), null);
        }
        string getCmbText(ComboBoxEx cmb)
        {
            string ret = "";
            Invoke(new MethodInvoker(() => ret = cmb.Text), null);
            return ret;
        }
        string getInputText(TextBoxX txtX)
        {
            string ret = "";
            Invoke(new MethodInvoker(() => ret = txtX.Text), null);
            return ret;
        }

        private void GetSQLServerInstancesName()
        {
            EnableBtn(btnInstanceName, false);
            //GetSQLServerInstancesLocal
            RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server");
            String[] instances = (String[])rk.GetValue("InstalledInstances");
            if (instances.Length > 0)
            {
                foreach (String element in instances)
                {
                    if (element == "MSSQLSERVER")
                    {
                        cmbExAdd(cmbSqlServer, System.Environment.MachineName);
                    }
                    else
                    {
                        cmbExAdd(cmbSqlServer, System.Environment.MachineName + @"\" + element);
                    }
                }
            }

            //GetSQLServerInstancesNetwork
            DataTable table = SqlDataSourceEnumerator.Instance.GetDataSources();
            foreach (DataRow server in table.Rows)
            {
                string servername = server[table.Columns["ServerName"]].ToString();

                // you can get that using the instanceName property 
                string instancename = server[table.Columns["InstanceName"]].ToString();

                //to form the servername you can combine the server and instancenames as
                string sqlserverfullname = String.Format(@"{0}\{1}", servername, instancename);

                cmbExAdd(cmbSqlServer, sqlserverfullname);

            }
            Invoke(new MethodInvoker(() => cmbSqlServer.SelectedIndex = 0), null);
            EnableBtn(btnInstanceName, true);
        }
 
        private void btnInstanceName_Click(object sender, EventArgs e)
        {
            cmbSqlServer.Items.Clear();
            Thread t = new Thread(new ThreadStart(GetSQLServerInstancesName));
            t.Start();
        }

        private void chkWindows_CheckedChanged(object sender, EventArgs e)
        {
            enableInput(false);
        }

        void enableInput(bool yes)
        {
            txtUserId.Enabled = yes;
            txtPassword.Enabled = yes;
        }

        private void chkSqlServer_CheckedChanged(object sender, EventArgs e)
        {
            enableInput(true);
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            builderConnect();
            Thread t = new Thread(new ThreadStart(LoginSqlServer));
            t.Start();
        }
        void builderConnect()
        {
            sqlBuilder.DataSource = cmbSqlServer.Text.Trim();
            
            sqlBuilder.InitialCatalog = cmbDatabase.Text.Trim();

            if (chkSqlServer.Checked)
            {
                sqlBuilder.UserID = txtUserId.Text.Trim();
                sqlBuilder.Password = txtPassword.Text.Trim();
                sqlBuilder.Remove("Integrated Security");
            }
            else
            {
                sqlBuilder.Remove("User ID");
                sqlBuilder.Remove("Password");
                sqlBuilder.IntegratedSecurity = true;
            }
        }
        void LoginSqlServer()
        {
            Invoke(new MethodInvoker(() => btnLogin.Enabled = false), null);
            SqlConnection conn = new SqlConnection(sqlBuilder.ConnectionString);
            try
            {
                conn.Open();
                Invoke(new MethodInvoker(() => cmbDatabase.Items.Clear()), null);
                this.loadDatabase();
                Invoke(new MethodInvoker(() => cmbDatabase.Enabled=true), null);
                Invoke(new MethodInvoker(() => cmbDatabase.SelectedIndex=0), null);
            }
            catch (SqlException ex)
            {
                if (ex.Number == 15151)
                    MsgBox.Show("Login does not exist.", "SQL Server Connection: #15151", MsgBoxButton.Ok, MsgBoxIcon.Warning);
                else if (ex.Number == 15007)
                    MsgBox.Show("Login already logged on.", "SQL Server Connection: #15007", MsgBoxButton.Ok, MsgBoxIcon.Warning);
                else
                    MsgBox.Show(String.Format("{0}: {1}", ex.Number, ex.Message), "SQL Server connection", MsgBoxButton.Ok, MsgBoxIcon.Warning);
            }
            finally
            {
                conn.Close();
                Invoke(new MethodInvoker(() => btnLogin.Enabled = true), null);
            }
        }
        void loadDatabase()
        {
            ServerConnection srvcon = new ServerConnection(getCmbText(cmbSqlServer));
            if (chkSqlServer.Checked == true)
            {
                srvcon.LoginSecure = false;
                srvcon.Login = getInputText(txtUserId);
                srvcon.Password = getInputText(txtPassword);
            }
            else
            {
                srvcon.LoginSecure = true;
            }
            
            Server srv = new Server(srvcon);
            foreach (Database db in srv.Databases)
            {
                Invoke(new MethodInvoker(() => cmbDatabase.Items.Add(db.Name)), null);
            }
        }

    }
}
